﻿using NSoup.Helper;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using System.Web.UI.HtmlControls;

namespace LunarSF.SHomeWorkshop.LunarMarkdownEditor.PythonHelp.CompleteKeywords
{
    internal class CompleteKeywordInfo
    {
        public CompleteKeywordInfo()
        {

        }

        private string keyword;
        /// <summary>
        /// 关键词。
        /// </summary>
        public string Keyword
        {
            get => this.keyword;
            set
            {
                if (value.StartsWith("--") && value.EndsWith("--"))
                {
                    keyword = value.Substring(2, value.Length - 4);
                    this.IsObsoleting = true;
                }
                else
                {
                    keyword = value;
                    this.IsObsoleting = false;
                }
            }
        }

        /// <summary>
        /// 是否已废弃。
        /// </summary>
        public bool IsObsoleting { get; set; } = false;

        private string description;
        /// <summary>
        /// 对关键词的描述。
        /// </summary>
        public string Description
        {
            get
            {
                return description;
            }
            set
            {
                var lines = value.Split(new string[] { "\r\n" }, System.StringSplitOptions.RemoveEmptyEntries);
                var sb = new StringBuilder();
                foreach (var line in lines)
                {
                    sb.Append(line.Trim(new char[] { '^', ' ', '　' }));
                }
                description = sb.ToString();
            }
        }

        /// <summary>
        /// 参数列表。
        /// </summary>
        public List<ArgInfo> Args { get; set; } = new List<ArgInfo>();

        /// <summary>
        /// 是否有参数。
        /// </summary>
        public bool HasArgs { get { return Args.Count > 0; } }

        /// <summary>
        /// 对方法返回值的描述。
        /// </summary>
        public string ReturnValueDescription { get; set; }

        /// <summary>
        /// 由主说明文本和参数列表的说明共同构成。
        /// </summary>
        public string FullDescription
        {
            get
            {
                var argDescription = "";

                switch (this.Type)
                {
                    case KeywordType.PropertyKeyword:
                        {
                            argDescription += "（实例属性）"; break;
                        }
                    case KeywordType.StaticPropertyKeyword:
                        {
                            argDescription += "（静态属性）"; break;
                        }
                    case KeywordType.MethodKeyword:
                        {
                            argDescription += "（实例方法）"; break;
                        }
                    case KeywordType.StaticMethodKeyword:
                        {
                            argDescription += "（静态方法）"; break;
                        }
                    case KeywordType.ConstructionMethod:
                        {
                            argDescription += "（构造方法）"; break;
                        }
                    case KeywordType.InnerFunction:
                        {
                            argDescription += "（内置函数）"; break;
                        }
                    case KeywordType.Class:
                        {
                            argDescription += "（类）"; break;
                        }
                    case KeywordType.EnumType:
                        {
                            argDescription += "（枚举类型）"; break;
                        }
                    case KeywordType.EnumValue:
                        {
                            argDescription += "（枚举值）"; break;
                        }
                }

                argDescription += this.Description + "\r\n";

                if (Args.Count > 0)
                {
                    var i = 1;
                    foreach (var arg in Args)
                    {
                        switch (arg.ArgType)
                        {
                            case ArgType.RString:
                                argDescription += $"  参数{i++}：原字符串型参数。" + arg.ArgDescription + "\r\n";
                                break;
                            case ArgType.String:
                                argDescription += $"  参数{i++}：字符串型参数。" + arg.ArgDescription + "\r\n";
                                break;
                            case ArgType.Bool:
                                argDescription += $"  参数{i++}：逻辑型（True|False）参数。" + arg.ArgDescription + "\r\n";
                                break;
                            case ArgType.Number:
                                argDescription += $"  参数{i++}：数值型参数。" + arg.ArgDescription + "\r\n";
                                break;
                            case ArgType.Object:
                                argDescription += $"  参数{i++}：对象型参数。" + arg.ArgDescription + "\r\n";
                                break;
                            case ArgType.EnumValue:
                                argDescription += $"  参数{i++}：枚举值型参数。" + arg.ArgDescription + "\r\n";
                                break;
                        }
                    }
                }

                if (string.IsNullOrWhiteSpace(ReturnValueDescription))
                {
                    argDescription += "（无返回值。）";
                }
                else
                {
                    argDescription += "（返回）" + ReturnValueDescription;
                }
                var result = argDescription.Trim(new char[] { ' ', '　', '\t', '\r', '\n' });
                return Regex.Replace(result, "<br> {0,}", "");
            }
        }

        public KeywordType Type { get; set; } = KeywordType.PropertyKeyword;


        private int backSelectOffset = 0;
        /// <summary>
        /// 自动完成后应退选的偏移值。
        /// 这个是根据参数列表自动计算出来的。
        /// </summary>
        public int BackSelectOffset
        {
            get
            {
                return backSelectOffset;
            }
        }

        /// <summary>
        /// 上屏的文本。如果是方法，需要添加参数列表。
        /// </summary>
        public string CompleteText
        {
            get
            {
                if (HasArgs == false)
                {
                    switch (this.Type)
                    {
                        case KeywordType.StaticMethodKeyword:
                        case KeywordType.ConstructionMethod:
                        case KeywordType.InnerFunction:
                        case KeywordType.MethodKeyword:
                            {
                                this.backSelectOffset = 1;
                                return Keyword + "()";
                            }
                        //case KeywordType.Class:
                        //case KeywordType.EnumType:
                        //case KeywordType.EnumValue:
                        //case KeywordType.StaticPropertyKeyword:
                        //case KeywordType.PropertyKeyword:
                        default:
                            {
                                this.backSelectOffset = 0;
                                return Keyword;
                            }
                    }
                }

                var resultText = Keyword + "(";
                var offset = 1;  // 右括号
                foreach (var arg in this.Args)
                {
                    if (arg.ArgDescription.StartsWith("[可缺省]"))
                    {
                        break;
                    }

                    switch (arg.ArgType)
                    {
                        case ArgType.Number:
                        case ArgType.Bool:
                        case ArgType.Object:
                            resultText += ", ";
                            offset += 2;
                            break;
                        case ArgType.String:
                            resultText += "\"\", ";
                            offset += 4;
                            break;
                        case ArgType.RString:
                            resultText += "r\"\", ";
                            offset += 5;
                            break;
                    }
                }
                if (resultText.EndsWith(", "))
                {
                    resultText = resultText.Substring(0, resultText.Length - 2);

                    if (Args[0].ArgType == ArgType.String)
                    {
                        offset -= 3;
                    }
                    else if (Args[0].ArgType == ArgType.RString)
                    {
                        offset -= 4;
                    }
                    else
                    {
                        offset -= 2;
                    }
                }
                this.backSelectOffset = offset;
                return resultText + ")";
            }
        }
    }

    internal class ArgInfo
    {
        public ArgType ArgType { get; set; }

        private string argDescription;

        public string ArgDescription
        {
            get
            {
                if (string.IsNullOrWhiteSpace(argDescription)) return string.Empty;

                return Regex.Replace(argDescription, "<br> {0,}", "");
            }
            set
            {
                argDescription = value;
            }
        }
    }

    internal enum ArgType
    {
        Number,
        String,
        Bool,
        Object,
        EnumValue,
        RString,
    }

    /// <summary>
    /// 一个方法可能是没有参数的，也可能只有一个参数，但都需要括号对！而变量或者关键词并不需要括号对。
    /// </summary>
    internal enum KeywordType
    {
        PropertyKeyword,
        StaticPropertyKeyword,
        MethodKeyword,
        StaticMethodKeyword,
        ConstructionMethod,
        InnerFunction,
        Class,
        EnumType,
        EnumValue,
    }
}
